/* SSP Plugin (Stevens Semantic Signal Processing Project)

   Copyright (C) 2011 xxu7@stevens.edu

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#ifndef SSP_PLUGIN_H
#define SSP_PLUGIN_H

/* gcc's header files */

#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "toplev.h"
#include "gimple.h"
#include "tree-pass.h"
#include "intl.h"
#include "langhooks.h"
#include "cfghooks.h"
#include "tree-iterator.h"
#include "real.h"
#include "cgraph.h"
#include "basic-block.h"
#include "tree-flow.h"

#include <mysql.h>

#define SQLSERVER "localhost"
#define SQLUSER "ssp"
#define SQLPASS "ssp"

#define SQL_STRING_ADDR sql_data.value + strlen(sql_data.value)
#define SQL_EXEC(X) if(mysql_query(conn, (X))) fprintf(stderr, "%s\n", mysql_error(conn))

#define MAX_OP_NUM 10

extern plugin_callback_func sspc_callback (void *, void *);
extern plugin_callback_func exit_callback (void *, void *);
extern plugin_callback_func io_callback (void *, void *);
typedef struct SSP_GIMPLE_DATA{
    gimple g;
    tree t;
    char *type;
    char *op0;
    char *op1;
    char *op2;
    int op_more;
    char *op0_more;
    unsigned int block;
    char *action;
}ssp_gimple_data;

typedef struct SSPC_DATA
{
		char *In_Function;
		MYSQL *conn;
}sspc_data;


typedef struct SSPC_SQL
{
	tree *t;
	unsigned int op[3];
	unsigned int number;
	char *decl_name;
        char value[100];
}sspc_sql;


static void print_tree_code_name(tree );
static tree ssp_func_debug (tree *, int *, void *);
static tree ssp_func_walk  (tree *, int *, void *);

void SSPC_hook_expr_fun(tree *, sspc_data *, int * );
void SSPC_hook_decl_fun(tree *, sspc_data *, int * );
void SSPC_hook_call_fun(tree *, sspc_data *, int * );
void SSPC_hook_stmt_fun(tree *, sspc_data *, int * );
void SSPC_hook_type_fun(tree *, sspc_data *, int * );
void SSPC_hook_const_fun(tree *, sspc_data *, int * );

void sql_init(MYSQL *);
void sql_create_database(MYSQL *, char *);
void sql_create_table(MYSQL *, char *);
void sql_add_ssp(MYSQL *, char *, sspc_sql);
void sql_stmt_list(tree *, char *, MYSQL *);
void sql_call(tree *, char *, MYSQL *);
void sql_del_dup(MYSQL *, char *);
void sql_ssp_pre_1(MYSQL *, char *);

char *tree2string(tree );

//function that pass will executed
unsigned int execute_ssp_io ( void );
static struct gimple_opt_pass pass_ssp_io = 
{
    {
        GIMPLE_PASS,
        "ssp_io",
        NULL,
        execute_ssp_io,
        NULL,
        NULL,
        0,
        0,
        PROP_cfg | PROP_ssa,
        0,
        0,
        0,
        TODO_verify_ssa | TODO_update_ssa 
    }
};

static void print_gimple(gimple g){
    if(g!=NULL)
        printf("DEBUG: GIMPLE = %s\n", gimple_code_name[gimple_code(g)]);
}
static void 
tree2num(tree t, char *dest){
    if (TREE_CODE(t) == INTEGER_CST)
    {
        sprintf(dest, "%d", TREE_INT_CST_LOW(t));
    }
    else if (TREE_CODE(t) == REAL_CST)
    {
        REAL_VALUE_TYPE d = TREE_REAL_CST(t);
        real_to_decimal(dest, &d, 10, 5, 1);
    }
}
#endif
